home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / progutil / iostream.zoo / src / streambu.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1991-09-22  |  4.8 KB  |  226 lines

  1. //    This is part of the iostream library, providing input/output for C++.
  2. //    Copyright (C) 1991 Per Bothner.
  3. //
  4. //    This library is free software; you can redistribute it and/or
  5. //    modify it under the terms of the GNU Library General Public
  6. //    License as published by the Free Software Foundation; either
  7. //    version 2 of the License, or (at your option) any later version.
  8. //
  9. //    This library is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. //    Library General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU Library General Public
  15. //    License along with this library; if not, write to the Free
  16. //    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #define RENAME_STDIO
  19. #include "ioprivat.h"
  20.  
  21. #ifdef __GNUG__
  22. #pragma implementation
  23. #endif
  24.  
  25. size_t streambuf::sputn(const char* s, size_t n) // OPTIMIZE THIS!
  26. {
  27.     size_t count = 0;
  28.     for (; count < n; count++) {
  29.     if (sputc(*s++) == EOF)
  30.         break;
  31.     }
  32.     return count;
  33. }
  34.  
  35. size_t streambuf::sgetn(char* s, size_t n) // OPTIMIZE THIS!
  36. {
  37.     size_t count = 0;
  38.     for (; count < n; count++) {
  39.     int ch = sbumpc();
  40.     if (ch == EOF)
  41.         break;
  42.     *s++ = ch;
  43.     }
  44.     return count;
  45. }
  46.  
  47. int streambuf::sync()
  48. {
  49.     if (gptr() == egptr() && pptr() == pbase())
  50.     return 0;
  51.     return EOF;
  52. }
  53.  
  54. int streambuf::pbackfail(int c)
  55. {
  56.     return EOF;
  57. }
  58.  
  59. streambuf* streambuf::setbuf(char* p, size_t len)
  60. {
  61.     setb(p, p+len, 0);
  62.     setp(0, 0);
  63.     setg(0, 0, 0);
  64.     return this;
  65. }
  66.  
  67. // I'm unclear what seekpos is supposed to accomplish.
  68. streampos streambuf::seekpos(streampos pos, int mode = ios::in|ios::out)
  69. {
  70.     return seekoff(pos, ios::beg, mode);
  71. }
  72.  
  73. void streambuf::setb(char* b, char* eb, int a)
  74. {
  75.     if (_base && (_flags & _S_USER_BUF))
  76.     free(_base);
  77.     _base = b;
  78.     _ebuf = eb;
  79.     if (a)
  80.     _flags &= ~_S_USER_BUF;
  81.     else
  82.     _flags |= _S_USER_BUF;
  83. }
  84.  
  85. #ifdef atarist
  86. extern "C" { extern unsigned long __DEFAULT_BUFSIZ__; }
  87.  
  88. int streambuf::doallocate()
  89. {
  90.     char *buf = malloc((size_t)__DEFAULT_BUFSIZ__);
  91.     if (buf == NULL)
  92.     return EOF;
  93.     setb(buf, buf+__DEFAULT_BUFSIZ__, 1);
  94.     return 1;
  95. }
  96. #else
  97. int streambuf::doallocate()
  98. {
  99.     char *buf = malloc((size_t)BUFSIZ);
  100.     if (buf == NULL)
  101.     return EOF;
  102.     setb(buf, buf+BUFSIZ, 1);
  103.     return 1;
  104. }
  105. #endif
  106.  
  107. #ifdef atarist
  108. extern "C" extern int __default_mode__;
  109. #endif
  110.  
  111. streambuf::streambuf()
  112. {
  113. #ifdef atarist
  114.   _flags = _IO_MAGIC | ((__default_mode__)? _S_IS_BINARY : 0);
  115. #else
  116.   _flags = _IO_MAGIC;
  117. #endif
  118.   _base = NULL;
  119.   _ebuf = NULL;
  120.   _eback = NULL;
  121.   _gptr = NULL;
  122.   _egptr = NULL;
  123.   _pbase = NULL;
  124.   _pptr = NULL;
  125.   _epptr = NULL;
  126.   _chain = NULL; // Not necessary.
  127. }
  128.  
  129. streambuf::~streambuf()
  130. {
  131.     if (_base && !(_flags & _S_USER_BUF))
  132.     free(_base);
  133. }
  134.  
  135. int streambuf::underflow()
  136. {
  137.     return EOF;
  138. }
  139.  
  140. int streambuf::overflow(int c = EOF)
  141. {
  142.     return EOF;
  143. }
  144.  
  145. streamoff streambuf::seekoff(streamoff, seek_dir, int mode=ios::in|ios::out)
  146. {
  147.     return EOF;
  148. }
  149.  
  150. int streambuf::sputbackc(char c)
  151. {
  152.     if (gptr() <= eback()) return pbackfail(c);
  153.     gbump(-1);
  154.     if (*gptr() != c)
  155.     *gptr() = c;
  156.     return (unsigned char)c;
  157. }
  158.  
  159. #ifdef IMPLEMENT_STDIO
  160. int __underflow(FILE* stream)
  161. {
  162.     return ((streambuf*)stream)->underflow();
  163. }
  164.  
  165. int __overflow(FILE* stream, int c)
  166. {
  167.     return ((streambuf*)stream)->overflow(c);
  168. }
  169. #endif
  170.  
  171. extern char vt_filebuf[1] asm(FILEBUF_VT_NAME);
  172.  
  173. struct fake_filebuf {
  174.     struct __streambuf s;
  175.     char* vtable;
  176.     struct __file_fields f;
  177. };
  178.  
  179. #ifdef LITTLE_ENDIAN
  180. #define INIT_FILE_FIELDS(FD) {0, 0, FD}
  181. #else
  182. #define INIT_FILE_FIELDS(FD) {FD, 0, 0}
  183. #endif
  184.  
  185. #define DEF_STD(NAME, FD, CHAIN, FLAGS) \
  186.     fake_filebuf NAME[1] = {{\
  187.        { _IO_MAGIC+_S_IS_FILEBUF+FLAGS, 0, 0, 0, 0, 0, 0, 0, 0, CHAIN},\
  188.        vt_filebuf,\
  189.        INIT_FILE_FIELDS(FD)}};
  190.  
  191. #
  192.  
  193. #ifndef atarist
  194. DEF_STD(CIN_STREAMBUF, 0, 0, _S_CAN_READ);
  195. DEF_STD(COUT_STREAMBUF, 1, (streambuf*)CIN_STREAMBUF, _S_CAN_WRITE);
  196. DEF_STD(CERR_STREAMBUF, 2, (streambuf*)COUT_STREAMBUF, _S_CAN_WRITE);
  197. #else
  198. DEF_STD(CIN_STREAMBUF, 0, 0, _S_CAN_READ+_S_LINE_BUF);
  199. DEF_STD(COUT_STREAMBUF, 1, (streambuf*)CIN_STREAMBUF, _S_CAN_WRITE+_S_LINE_BUF);
  200. DEF_STD(CERR_STREAMBUF, 2, (streambuf*)COUT_STREAMBUF, _S_CAN_WRITE+_S_LINE_BUF);
  201. /* this bombs
  202. DEF_STD(CERR_STREAMBUF, 2, (streambuf*)COUT_STREAMBUF, _S_CAN_WRITE+_S_UNBUFFERED);
  203. */
  204. #endif
  205.  
  206. DEF_STD(not_open_filebuf, -1, (streambuf*)0, 0);
  207.  
  208. streambuf* __stream_list = (streambuf*)CERR_STREAMBUF;
  209.  
  210. static void flush_all()
  211. {
  212.     streambuf *stream;
  213.     for (stream = __stream_list; stream != NULL; stream = stream->_chain)
  214.     stream->overflow(EOF);
  215. }
  216.  
  217. struct __io_defs {
  218.     __io_defs() { }
  219.     ~__io_defs() { flush_all(); }
  220. };
  221. __io_defs io_defs__;
  222.  
  223. #ifdef IMPLEMENT_STDIO
  224. extern "C" void _cleanup() { flush_all(); } // For GNU libc.
  225. #endif
  226.